package com.example.simplesvc.concurrent.lock;

import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.util.concurrent.Callable;
import java.util.function.Function;

public class DBLock {

    private String name;

    private SqlSessionFactory ssf;

    private static Logger log = LoggerFactory.getLogger(DBLock.class);

    public DBLock(String name, SqlSessionFactory ssf) {
        this.name = name;
        this.ssf = ssf;
    }


    public void executeWithLock(Callable call) {
        SqlSession session = ssf.openSession();
        Connection connection = session.getConnection();

        try {
            boolean autoCommit = connection.getAutoCommit();
            connection.setAutoCommit(false);
            PreparedStatement pps = session
                    .getConnection()
                    .prepareStatement("select 1 from distribution_lock where name=? for update");
            pps.setString(1, name);
            pps.execute();
            try {
                call.call();
            } finally {
                connection.commit();
                connection.setAutoCommit(autoCommit);
            }


        } catch (Exception e) {
            log.warn("获取锁失败", e);
        }
    }


}
